import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
from matplotlib.patches import Wedge
from datetime import datetime

# ---------------------- 1. 路径与样式设置 ----------------------
# 使用您提供的准确数据路径
ROOT_DIR = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验"
DATA_PATH = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\data\erp_order_data.xlsx"
SAVE_PATH = os.path.join(ROOT_DIR, "results", "22_仪表盘图.png")

# 设置统一的视觉风格
plt.rcParams.update({
    'font.sans-serif': ['SimHei'],
    'axes.unicode_minus': False,
    'axes.facecolor': '#1A1A2E',
    'figure.facecolor': '#1A1A2E',
    'text.color': 'white',
    'xtick.color': 'white',
    'ytick.color': 'white',
    'grid.color': '#4A4A6A',
    'axes.linewidth': 1.5
})

# ---------------------- 2. 仪表盘数据准备 ----------------------
try:
    # 尝试加载ERP订单数据
    df = pd.read_excel(DATA_PATH)
    print(f"成功加载ERP订单数据，总记录数: {len(df)}")

    # 计算运营指数
    # 从知识库中获取参考值，假设运营指数基于订单完成率
    completed_orders = len(df[df['status'].isin(['已完成', '已发货'])])
    total_orders = len(df)
    completion_rate = completed_orders / total_orders

    # 将完成率映射到50-150范围内
    current_value = 50 + completion_rate * 100

    # 限制在50-150范围内
    current_value = max(50, min(150, current_value))

except Exception as e:
    print(f"加载数据失败: {e}")
    # 使用预设值
    current_value = 76

# 设置仪表盘参数
center = (0, 0)
radius = 1.0
min_value = 50
max_value = 150
title = "2022年6月29公司整体运营指数良好"

# ---------------------- 3. 绘制仪表盘图 ----------------------
fig, ax = plt.subplots(figsize=(14, 9))
ax.set_aspect('equal')

# 1. 绘制背景（深蓝色）
background = plt.Circle(center, radius * 1.3, color='#1A1A2E', ec='none')
ax.add_patch(background)

# 2. 绘制仪表盘彩色环
# 颜色分段：蓝色(50-80), 深红色(80-100), 黄色(100-120), 粉红色(120-150)
color_zones = [
    ('#4BB5C2', 50, 80),  # 蓝色区域
    ('#5C1E2B', 80, 100),  # 深红色区域
    ('#FFB94F', 100, 120),  # 黄色区域
    ('#E56A72', 120, 150)  # 粉红色区域
]

for color, start, end in color_zones:
    # 将值映射到角度 (0-360)
    start_angle = 180 + (start - min_value) / (max_value - min_value) * 180
    end_angle = 180 + (end - min_value) / (max_value - min_value) * 180
    wedge = Wedge(center, radius, start_angle, end_angle, width=0.15,
                  facecolor=color, edgecolor='white', linewidth=1.5)
    ax.add_patch(wedge)

# 3. 绘制刻度和数值
for value in range(min_value, max_value + 10, 10):
    angle = 180 + (value - min_value) / (max_value - min_value) * 180
    theta = np.radians(angle)

    # 计算刻度线位置
    x1 = radius * 0.85 * np.cos(theta)
    y1 = radius * 0.85 * np.sin(theta)
    x2 = radius * 0.95 * np.cos(theta)
    y2 = radius * 0.95 * np.sin(theta)

    # 绘制刻度线
    ax.plot([x1, x2], [y1, y2], color='white', linewidth=1.5)

    # 绘制刻度值
    x_text = radius * 1.1 * np.cos(theta)
    y_text = radius * 1.1 * np.sin(theta)
    ax.text(x_text, y_text, str(value), fontsize=14, ha='center', va='center', color='white')

# 4. 绘制指针
angle = 180 + (current_value - min_value) / (max_value - min_value) * 180
theta = np.radians(angle)
x_end = radius * 0.7 * np.cos(theta)
y_end = radius * 0.7 * np.sin(theta)
ax.plot([0, x_end], [0, y_end], color='white', linewidth=3)

# 5. 绘制指针中心圆点 - 修复警告
# 修正：使用facecolor代替color，避免与edgecolor冲突
ax.add_patch(plt.Circle(center, 0.06, facecolor='white', edgecolor='none'))

# 6. 添加中心数值
ax.text(0, 0, f'{int(current_value)}', fontsize=50, fontweight='bold',
        ha='center', va='center', color='white')

# 7. 添加标题
ax.set_title(title, fontsize=24, fontweight='bold', pad=30, color='white')

# 8. 添加数据来源
current_date = datetime.now().strftime('%Y.%m.%d')
ax.text(0.5, 0.05,
        f'*注：数据来源于公司运营系统，统计日期截至{current_date}',
        ha='center', va='center', transform=ax.transAxes,
        fontsize=12, color='#B0B0B0', alpha=0.7)

# 设置坐标轴范围，确保所有内容可见
ax.set_xlim(-1.5, 1.5)
ax.set_ylim(-1.5, 1.5)

# 隐藏坐标轴
ax.axis('off')

# 确保布局紧凑
plt.tight_layout(rect=[0, 0.05, 1, 0.95])

# 确保结果目录存在
os.makedirs(os.path.dirname(SAVE_PATH), exist_ok=True)

# 保存图片
plt.savefig(SAVE_PATH, dpi=300, bbox_inches='tight', facecolor='#1A1A2E', edgecolor='none')
plt.close()

print("\n✅ 仪表盘图生成成功！")
print(f"📁 保存路径：{SAVE_PATH}")
print(f"📊 当前运营指数：{int(current_value)}")
print("💡 仪表盘颜色说明：蓝色(50-80)、深红色(80-100)、黄色(100-120)、粉红色(120-150)")